/*
 * Copyright 2009-2010 Nanjing RedOrange ltd (http://www.red-orange.cn)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package redora.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.ui.*;
import redora.client.Persistable;
import redora.client.mvp.ClientFactory;
import redora.client.mvp.EditPlace;
import redora.client.mvp.FindEvent;

import java.util.logging.Logger;

import static java.util.logging.Level.INFO;
import static redora.client.Persistable.Scope.List;

/**
 * A Anchor style widget that produces a popup (when clicked) with a table
 * of Scope.List records queried from given parentId and defaultFinder.<br>
 * The anchor will either show '?' or the number of records in pre-mentioned
 * query. If the query results in 0 records, the popup is suppressed.<br>
 * The records in the popup grid are clickable. When clicked, focus will move
 * to the EditPlace of clicked item.<br>
 * The widget uses the cache service and has listeners on it's members. When
 * a member of the list is updated elsewhere, the change will synced.<br>
 * The popup and the grid are styled as redoraListPopup.
 * @author Nanjing Redorange (www.red-orange.cn)
 */
public class ListPopup extends Composite {
    static Logger l = Logger.getLogger("ListPopup");

    static RedoraResource redoraResource = GWT.create(RedoraResource.class);

    final SimplePanel panel;
    final Anchor label;
    final ClientFactory clientFactory;
    final Long parentId;
    final String url;
    final Class<? extends Persistable> childClass;
    final Popup popup;

    public ListPopup(ClientFactory clientFactory, Long parentId, int defaultFinder, Class<? extends Persistable> childClass) {
        this.clientFactory = clientFactory;
        this.parentId = parentId;
        this.url = clientFactory.getLocator().locateService(childClass).url(defaultFinder, parentId);
        this.childClass = childClass;

        popup = new Popup();
        panel = new SimplePanel();
        label = new Anchor(clientFactory.getLocator().locateService(childClass).useCache(url)
                ? Integer.toString(clientFactory.getLocator().locateService(childClass).cache(url).length)
                : "?");
        panel.setWidget(label);
        this.initWidget(panel);
        bind();
    }

    private void bind() {
        label.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                panel.clear();
                panel.setWidget(new Image("images/loading.gif"));
                clientFactory.getLocator().locateService(childClass).finder(url, List);

                popup.setPopupPosition(event.getClientX(), event.getClientY());
//                popup.setPopupPosition(
//                        event.getRelativeElement().getAbsoluteLeft() - 150
//                        , event.getRelativeElement().getAbsoluteBottom());
                popup.show();
            }
        });
        clientFactory.getEventBus().addHandler(FindEvent.TYPE,
                new FindEvent.Handler() {
                    @Override
                    public void onSuccess(FindEvent event) {
                        if (event.cls == childClass && event.finderKey.equals(url)) {
                            l.log(INFO, "Processing " + event.results.length + " FindEvent results for " + childClass + ": " + event.finderKey);
                            label.setText(Integer.toString(event.results.length));
                            popup.setRows(event.results);
                            //popup.show();
                            panel.clear();
                            panel.setWidget(label);
                        }
                    }
                });
    }

    class Popup extends PopupPanel {
        final Grid grid;

        public Popup() {
            super(true);
            setStyleName(redoraResource.css().redoraListPopup());
            setAnimationEnabled(true);
            setAutoHideEnabled(true);
            final ScrollPanel panel = new ScrollPanel();
            panel.setWidth("100%");
            add(panel);

            grid = new Grid();
            grid.addStyleName(redoraResource.css().redoraListPopup());
            panel.add(grid);
        }

        public void setRows(Long[] ids) {
            grid.clear();
            if (ids.length == 0) {
                hide();
            } else {
                grid.resize(ids.length, 1);
                for (int i = 0; i < ids.length; i++) {
                    Anchor link = new Anchor(
                            new SafeHtmlBuilder().appendEscaped(
                                    clientFactory.getLocator().locateService(childClass).cache(ids[i]).toListString())
                                    .toSafeHtml());
                    link.setHref(new EditPlace(childClass, ids[i]).toString());
                    grid.setWidget(i, 0, link);
                }
            }
        }
    }
}
